package com.example.mallcoupon.service.Impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mallcoupon.mapper.CouponMapper;
import com.example.mallcoupon.mapper.InsertTCCMapper;
import com.example.mallcoupon.pojo.TCoupon;
import com.example.mallcoupon.pojo.Tcc;
import com.example.mallcoupon.service.CouponService;
import com.example.mallcoupon.service.InsertTCCService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class InsertTCCServiceImpl extends ServiceImpl<InsertTCCMapper, Tcc>  implements InsertTCCService {
	@Autowired
	CouponService couponService;


	@Override
	public void insert(String name, Integer age) {
		// 防止业务悬挂，先判断有没有tcc表中有没有记录，如果有，一定是cancel执行过，要拒绝业务
		// 1、获取事务id
		String xid = RootContext.getXID();
		// 2、判断是否有记录
		Tcc byId = this.getById(xid);
		if (byId!=null){
			// cancel执行过，拒绝执行业务
			return;
		}

		// 业务
		TCoupon tCoupon = new TCoupon();
		tCoupon.setName(name);
		tCoupon.setAge(age);
		couponService.save(tCoupon);

		// 记录事务状态和业务id
		Tcc tcc = new Tcc();
		tcc.setBusinessId(tCoupon.getId());
		tcc.setState(0); // 0是try
		this.save(tcc);
	}

	@Override // 成功的方法
	public boolean confirm(BusinessActionContext context) {
		// 获取事务id
		String xid = context.getXid();
		// 根据id删除tcc记录
		boolean b = this.removeById(xid);
		return b;
	}

	@Override // try的反向，恢复业务修改的数据
	public boolean cancel(BusinessActionContext context) {
		// 获取事务id
		String xid = context.getXid();
		// 查询tcc表，获取我们寸的businessId
		Tcc tcc = this.getById(xid);

		// -----空回滚的判断，为null证明try没执行，需要空回滚,就是再添加一条tcc记录，state存cancel-----
		if (tcc == null){
			// 记录事务状态和业务id
			tcc = new Tcc();
			tcc.setBusinessId(context.getActionContext("name").toString()); // 从try传的参数获取，这个字段值要唯一
			tcc.setState(2); // 2是cancel
			this.save(tcc);
			return true;
		}

		// ----幂等处理，状态判断，防止重复处理-------
		if (tcc.getState() == 2){ // 已经提交过了
			return true;
		}


		// 根据businessId删除我们业务里新增的数据
		boolean b = couponService.removeById(tcc.getBusinessId());
		return b;
	}
}
